<!---: Extend Locode App with Custom PetiteVue Components -->

<script minify>
App.components({
    NewAlbums({ store, routes, settings, state, save, done }) {
        return {
            $template: '#new-album-template',
            store, routes, settings,
            get state() { return state && state() },
            get apiState() { return map(this.state, x => x.apiCreate) },
            get model() { return map(this.apiState, x => x.model) || {} },
            inputClass(prop,cls) { return inputClass(this.apiState.fieldError(prop),cls) },

            done,
            submit() {
                this.apiState.apiForm(new FormData(this.$refs.form))
                    .then(r => {
                        if (r.api.succeeded) {
                            save()
                            done()
                        }
                    })
            }
        }
    },
    
    EditAlbums({ store, routes, settings, state, save, done }) {
        return {
            $template: '#edit-album-template',
            store, routes, settings,
            get state() { return state && state() },
            get apiState() { return map(this.state, x => x.apiPatch) },

            api: null,
            errorSummary: null,
            model: state().apiPatch.model,
            origModel: {},

            done,
            submit() {
                this.apiState.apiForm(new FormData(this.$refs.form))
                    .then(r => {
                        if (r.api.succeeded) {
                            save()
                            done()
                        }
                    })
            },

            updated() {
                let state = this.state
                if (!state || !state.opQuery || !routes.edit) return

                this.model = this.apiState.model
                this.errorSummary = ''
                let apiQuery = state.apiQuery
                apiQuery.apiSend({ albumId:routes.edit })
                    .then(r => {
                        let results = map(r.api.response, x => x.results)
                        if (apiQuery.errorSummary) this.errorSummary = apiQuery.errorSummary
                        this.api = r.api
                        this.origModel = this.apiState.createModel(results[0])
                        this.model = Object.assign({}, this.origModel)
                    })
            },

            mounted() { routes.onEditChange(() => this.updated()) },
            unmounted() { routes.onEditChange(null) },
        }
    },
    
    SubmitAlbumButton: '#submit-album-template'
})
</script>

<style>
.album-form form {
    background-image: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 512 512'%3E%3Cpath fill='%23C5CFD1' fill-opacity='0.7' d='M256 19C124.746 19 18.344 125.402 18.344 256.656S124.746 494.311 256 494.311s237.656-106.402 237.656-237.656S387.254 19 256 19zm0 287.266c-27.399 0-49.61-22.211-49.61-49.61s22.211-49.61 49.61-49.61s49.61 22.211 49.61 49.61s-22.211 49.61-49.61 49.61z'/%3E%3Cpath fill='%23EDEDED' d='m144.943 220.959l-89.429-30.268c-3.84-1.3-5.878-5.522-4.451-9.317C72.11 125.409 115.148 79.486 168.12 56.454c3.723-1.619 8.047.224 9.526 4.005l34.413 87.955c1.378 3.522-.212 7.49-3.624 9.122c-23.774 11.37-43.933 33.294-54.524 59.318a7.192 7.192 0 0 1-8.968 4.105zm213.146 75.499c-10.591 26.024-30.75 47.948-54.524 59.318c-3.412 1.632-5.003 5.6-3.624 9.122l34.413 87.955c1.479 3.781 5.803 5.623 9.526 4.005c52.972-23.032 96.011-68.956 117.057-124.921c1.427-3.794-.611-8.017-4.451-9.317l-89.429-30.268a7.192 7.192 0 0 0-8.968 4.106z'/%3E%3Cpath fill='%23798A93' d='M256 347.109c-49.876 0-90.454-40.577-90.454-90.454s40.578-90.454 90.454-90.454c49.877 0 90.454 40.578 90.454 90.454S305.877 347.109 256 347.109zm0-158.45c-37.494 0-67.997 30.503-67.997 67.997s30.503 67.997 67.997 67.997s67.997-30.503 67.997-67.997s-30.503-67.997-67.997-67.997z'/%3E%3C/svg%3E");
}
.album-form #title-error, .album-form #artistId-error {
    font-size: 0.875rem;
    line-height: 1.25rem;
    margin-top: .5rem;
    color: #fff;
    background: rgba(239, 68, 68, 0.8);
    padding: .5rem;
    border-radius: 0.25rem;
}
.album-form input, .album-form .lookup {
    max-width: 21rem;
}
</style>

<template id="new-album-template">
<div v-if="apiState" class="album-form flex justify-center">
    <div class="relative flex flex-col">
        <div v-scope="CloseButton({ onclick:done })" title="Close"></div>
        <div v-if="apiState.errorSummary" v-scope="ErrorSummary({ errorSummary: () => apiState.errorSummary })"></div>
        <form ref="form" @submit.prevent="submit" class="shadow-md rounded-full w-96 h-96 flex justify-center items-center">
            <div class="flex flex-col justify-center items-center text-center">
                <h1 class="text-3xl font-medium text-rose-500 mb-4">New Album</h1>
                <fieldset>
                    <!---: Using custom input -->
                    <div class="mb-4">
                        <input type="text" name="Title" :class="inputClass('Title')" placeholder="Album Title">
                        <p id="title-error" v-if="apiState.fieldError('Title')" v-html="apiState.fieldError('Title')"></p>
                    </div>

                    <!---: Using Input Lookup component -->
                    <div v-scope="Input({ field:apiState.field('ArtistId', f => {f.input.label='';f.input.placeholder='Select Artist'}), model, api:() => apiState.api })" class="mb-4"></div>

                    <div v-scope="SubmitAlbumButton()"></div>
                </fieldset>
            </div>
        </form>
    </div>
</div>
</template>

<template id="edit-album-template">
<div v-if="apiState" class="album-form flex justify-center" @vue:mounted="mounted" @vue:unmounted="unmounted">
    <div class="relative flex flex-col">
        <div v-scope="CloseButton({ onclick:done })" title="Close"></div>
        <div v-if="apiState.errorSummary" v-scope="ErrorSummary({ errorSummary: () => apiState.errorSummary })"></div>
        <form ref="form" @submit.prevent="submit" class="shadow-md rounded-full w-96 h-96 max-w-96 flex justify-center items-center">
            <div class="flex flex-col justify-center items-center text-center">
                <h1 class="text-3xl font-medium text-rose-500 mb-4">Edit Album {{model.albumId}}</h1>
                <fieldset>
                    <input type="hidden" name="albumId" :value="model.albumId">
                    <!---: Using built-in Input components without labels -->
                    <div v-scope="Input({ field:apiState.field('Title', f => f.input.label=''), model:() => model, api:() => apiState.api })" class="mb-4"></div>
                    <div v-scope="Input({ field:apiState.field('ArtistId', f => {f.input.label='';f.input.placeholder='Select Artist'}), model:() => model, api:() => apiState.api })" class="mb-4"></div>
                    <div v-scope="SubmitAlbumButton()"></div>
                </fieldset>
            </div>
        </form>
    </div>
</div>
</template>

<!---: Reuse functionality with custom components -->
<template id="submit-album-template">
<button type="submit" class="inline-flex items-center p-3 border border-transparent rounded-full shadow-sm text-white bg-rose-600 hover:bg-rose-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-rose-500">
    <svg class="h-8 w-8" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" preserveAspectRatio="xMidYMid meet" viewBox="0 0 48 48">
        <g fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="4">
            <path stroke-linecap="round" d="M24 44C12.954 44 4 35.046 4 24S12.954 4 24 4s20 8.954 20 20"/>
            <path d="M20 24v-6.928l6 3.464L32 24l-6 3.464l-6 3.464V24Z"/><path stroke-linecap="round" d="M37.05 32v10M42 36.95H32"/>
        </g>
    </svg>
</button>
</template>
